package cn.lyjuan.archetypes.bms.web.service;


import cn.lyjuan.archetypes.bms.web.util.ErrUtils;
import cn.lyjuan.base.util.ReflectUtils;
import cn.lyjuan.archetypes.bms.common.util.BmsMapper;
import org.springframework.beans.factory.annotation.Autowired;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public abstract class BaseService<T>
{
    @Autowired
    protected BmsMapper<T> mapper;

    public void save(T entity)
    {
        mapper.insert(entity);
    }

    public T queryById(Integer id)
    {
        return (T) mapper.selectByPrimaryKey(id);
    }

    public boolean exist(Integer id)
    {
        return mapper.existsWithPrimaryKey(id);
    }

    public void updateWithoutNull(T t)
    {
        mapper.updateByPrimaryKeySelective(t);
    }

    /**
     * 使用简单的 and key = val 拼接 where 查询
     * @param map
     */
    public List<T> findByExample(Map<String, Object> map)
    {
        if (null == map || map.isEmpty())
            return new ArrayList<>();

        Class currGenericity = ReflectUtils.getGenericityClass(this.getClass(), 0);

        Example.Criteria criteria = new Example(currGenericity)
                .createCriteria();

        for (Iterator<Map.Entry<String, Object>> it = map.entrySet().iterator(); it.hasNext(); )
        {
            Map.Entry<String, Object> entry = it.next();
            criteria.andEqualTo(entry.getKey(), entry.getValue());
        }

        return mapper.selectByExample(currGenericity);
    }

    /**
     * 使用简单的 and key = val 拼接 where 查询
     * @param map
     * @return      如果找不到，返回null，如果有多个，抛出 AppException异常
     */
    public T findOneByExample(Map<String, Object> map)
    {
        List<T> list = findByExample(map);

        if (null == list || list.isEmpty())
            return null;

        if (list.size() > 1)
            ErrUtils.appThrow("select one but result multi");

        return list.get(0);
    }

    public T selectOneByExample(Example example)
    {
        List<T> list = mapper.selectByExample(example);

        if (list.isEmpty())
            return null;

        if (list.size() > 1)
            ErrUtils.appThrow("select one but result multi");

        return list.get(0);
    }
}
